package com.atjava.nebula.web.action;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.atjava.nebula.core.dao.ibatis.Condition;
import com.atjava.nebula.core.exception.baseExp.SystemException;
import com.atjava.nebula.core.model.BaseModel;
import com.atjava.nebula.core.service.GenericService;
import com.atjava.nebula.core.service.InterceptService;
import com.atjava.nebula.core.service.impl.GenericServiceImpl;
import com.atjava.nebula.core.tablexml.view.Property;
import com.atjava.nebula.core.tablexml.view.Query;
import com.atjava.nebula.core.util.context.SpringContextHolder;
import com.atjava.nebula.core.util.func.StringUtil;
import com.atjava.nebula.core.util.reflection.ReflectUtil;
import com.atjava.nebula.web.util.XmlViewVariableUtil;
import com.atjava.nebula.web.view.XmlViewManager;

/**
 * Action基类.
 * @param <T> CRUD对象的类型
 * 
 */
public abstract class BaseAction  {
	
public static final String VIEW_PATH_LIST = "/base/list-view";
	
	//public static final String MODEL_KEY_DATALIST = "nebula_framework_datalist";
	public static final String MODEL_KEY_XMLVIEW = "nebula_model_xmlview";
	public static final String MODEL_KEY_CATALOG = "nebula_model_catalog";
	public static final String MODEL_KEY_VIEWCFG = "nebula_model_viewcfg";
	public static final String MODEL_KEY_SYSMENU = "nebula_model_sysmenu";
	public static final String MODEL_KEY_SYSUSER = "nebula_model_sysuser";
	
	//public static final String QUERY_KEY_PAGING = "frames_paging";
	//public static final String QUERY_KEY_QUERYMAP = "nebula_querymap";
	//
	
	
	public static final String REQ_PARAM_QUERYPK = "nebula_req_param_querypk";
	
	//public static final String REQUEST_KEY_GRID = "nebula_request_grid";
	
	public static final String REQ_PARAM_PAGENO = "nebula_req_param_pageno";
	public static final String REQ_PARAM_GRIDID = "nebula_req_param_gridid";
	public static final String REQ_PARAM_TREEID = "nebula_req_param_treeid";
	public static final String REQ_PARAM_QUERYID = "nebula_req_param_queryid";
	public static final String REQ_PARAM_CATALOG = "nebula_req_param_catalog";
	public static final String REQ_PARAM_ENTITY = "nebula_req_param_entity";
	public static final String REQ_PARAM_COMPNAME = "nebula_req_param_compname";
	
	protected final Logger logger = LoggerFactory.getLogger(getClass());
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected GenericService<?,?> getService(String catalog,String entity,String intercept) {
		Class<?> entityClass = XmlViewManager.getEntityClass(catalog, entity);
		GenericService<?,?> baseService = new GenericServiceImpl(entityClass);
		if(StringUtils.isNotBlank(intercept)){
			InterceptService interceptService = (InterceptService)SpringContextHolder.getBean(intercept);
			baseService.setIntercept(interceptService);
		}
		return baseService;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected GenericService<?,?> getService(String catalog,String entity,InterceptService interceptService) {
		Class<?> entityClass = XmlViewManager.getEntityClass(catalog, entity);
		GenericService<?,?> baseService = new GenericServiceImpl(entityClass);
		if(interceptService != null){
			baseService.setIntercept(interceptService);
		}
		return baseService;
	}
	
	protected GenericService<?,?> getService(String catalog,String entity) {
		InterceptService interceptService = null;
		return getService(catalog, entity, interceptService);
	}
	
	protected  <T extends BaseModel,ID extends Serializable> GenericService<T,ID>
	getService(Class<T> entityClass,Class<ID> idCls) {
		GenericService<T,ID> baseService = new GenericServiceImpl<T,ID>(entityClass);
		return baseService;
	}
	
	protected GenericService<?,?> getService(String dataset) {
		InterceptService interceptService = null;
		int splitIndex = dataset.indexOf(".");
		String catalog = dataset.substring(0,splitIndex);
		String entity = dataset.substring(splitIndex+1);
		return getService(catalog, entity, interceptService);
	}
	
	public Object getModelFromRequest(Class<?> clazz,HttpServletRequest req) 
			throws SystemException{
		
		Field [] fields = clazz.getDeclaredFields();
		
		Object target = null;
		try {
			target = clazz.newInstance();
			for (int i = 0; i < fields.length; i++) {
				String name = fields[i].getName();
				String value = req.getParameter(name);
				value = XmlViewVariableUtil.evalSystemVariables(value);
				if(value != null){
					ReflectUtil.setFieldValue(target, name, value);
				}
			}
		} catch (Exception e) {
			throw new SystemException(e,"Get instance of ["+clazz.getName()+"] from request.");
		}
		return target;
	}
	
	public static Condition getConditionFromRequest(
			HttpServletRequest request,Query query){
		
		Condition cond = new Condition();
		
		if(query == null)
			return cond;
		
		List<Property> properties = query.getProperties();
		for (int i = 0; i < properties.size(); i++) {
			Property prop = properties.get(i);
			String key = prop.getName();
			String value = request.getParameter(key);
			String symbol = prop.getCond();
			if(StringUtils.isNotBlank(value)){
				if("%".equals(symbol)){
					cond.addCriterion(StringUtil.toUnderlineName(key), "like", "%" + value + "%");
				}else{
					cond.addCriterion(StringUtil.toUnderlineName(key), symbol, value);
				}
			}
		}
		return cond;
	}
}
